/************************************************************************
 * AudioLogger class implementation
 *
 * (c) Robert Bosch GmbH, CR/AEH
 *
 *	Author: CR/AEH-Steffens
*************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "AudioLogger.h"
#include "UILogger.h"

AudioLogger::AudioLogger(AudioFormat format) 
{
	m_hLogFile 			 = NULL;
	m_sessionID 		 = 0;
	m_ulBufferLength 	 = 0;
	m_format.nBits		 = format.nBits;
	m_format.nChannels	 = format.nChannels;
	m_format.nSampleRate = format.nSampleRate;
}

AudioLogger::~AudioLogger() 
{
}

bool AudioLogger::createLogFile(const char* szLogFileName, int sessionID)
{
	if (szLogFileName == NULL)
		return false;

	// Open Audio log file for writing
	m_hLogFile = fopen(szLogFileName, "rw+");
	if (m_hLogFile == NULL) {
		UILogger::getInstance()->err(MODULE_SpeechManager, "AudioLogger", "Failed to open log file!\n");
		return false;
	}

	m_ulBufferLength = 0;
	writeHeader();
	m_sessionID = sessionID;
	m_logFileName = std::string(szLogFileName);
	return true;
}

void AudioLogger::writeHeader()
{
	unsigned long bytesWritten = 0;
	char* fileLengthString = NULL;
	char* shortValueString = NULL;
	char* longValueString = NULL;
	char* riff = NULL;
	char* wave = NULL;
	char* fmt = NULL;
	char* data = NULL;

	strcpy(riff, "RIFF");
	strcpy(wave, "WAVE");
	strcpy(fmt,  "fmt ");
	strcpy(data, "data");

	fseek(m_hLogFile,0,SEEK_SET);
	printf(riff,4,&bytesWritten,NULL);

	unsigned temporaryFileLength = m_format.nSampleRate*(m_format.nBits/8)/2 + 36; // half second is min
	sprintf(fileLengthString, "%u", temporaryFileLength);
	printf(fileLengthString,4,&bytesWritten,NULL);

	printf(wave,4,&bytesWritten,NULL);
	printf(fmt,4,&bytesWritten,NULL);

	unsigned longValue = 0x10; // fmt length
	sprintf(longValueString, "%u", longValue);
	printf(longValueString,4,&bytesWritten,NULL);

	unsigned short shortValue = 1;  // 1 = pcm
	sprintf(shortValueString, "%d", shortValue);
	printf(shortValueString,2,&bytesWritten,NULL);

	shortValue = m_format.nChannels;	// channel
	sprintf(shortValueString, "%d", shortValue);
	printf(shortValueString,2,&bytesWritten,NULL);

	longValue = m_format.nSampleRate;	// samples / second
	sprintf(longValueString, "%u", longValue);
	printf(longValueString,4,&bytesWritten,NULL);

	longValue = m_format.nSampleRate * m_format.nBits / 8; // bytes per second
	sprintf(longValueString, "%u", longValue);
	printf(longValueString,4,&bytesWritten,NULL);

	shortValue = 2; // block align
	sprintf(shortValueString, "%d", shortValue);
	printf(shortValueString,2,&bytesWritten,NULL);

	shortValue = m_format.nBits; // bits per sample
	sprintf(shortValueString, "%d", shortValue);
	printf(shortValueString,2,&bytesWritten,NULL);

	printf(data,4,&bytesWritten,NULL);

	longValue = temporaryFileLength - 36;
	sprintf(longValueString, "%u", longValue);
	printf(longValueString,4,&bytesWritten,NULL);

	m_ulBufferLength = 0;
}

void AudioLogger::closeLogFile()
{
	unsigned long bytesWritten = 0;
	char * fileLengthString = NULL;
	char * bufferLengthString = NULL;

	// set file Length on pos 4
	fseek(m_hLogFile,4,SEEK_SET);
	unsigned bufferLength = m_ulBufferLength;
	unsigned fileLength = m_ulBufferLength + 36;  // file length - 8
	sprintf(fileLengthString, "%u", fileLength);
	printf(fileLengthString,4,&bytesWritten,NULL);

	// set file Length on pos 40
	fseek(m_hLogFile,40,SEEK_SET);
	sprintf(bufferLengthString, "%u", bufferLength);
	printf(bufferLengthString,4,&bytesWritten,NULL);

	// flush and close file
	fseek(m_hLogFile,0,SEEK_END);
	fclose(m_hLogFile);
}

void AudioLogger::writeBufferToFile(void* pBuffer, unsigned long ulBufSize)
{
	unsigned long ulBytesWritten;

	if(printf((char *)pBuffer, ulBufSize, &ulBytesWritten, NULL) == 0)
		UILogger::getInstance()->err(MODULE_SpeechManager, "AudioLogger", "Function WriteFile failed in writeBufferToFile!\n");

	m_ulBufferLength += ulBytesWritten;
}
